package cases

import (
	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
	beego "github.com/beego/beego/v2/server/web"
	"strconv"
	"time"
	"xpms/app/models"
	"xpms/cores"
	"xpms/cores/utils"
)

type TestCase struct {
	Id            int64 `orm:"pk;column(caseid);" json:"Id,string"`
	Projectid     int64 `json:"Projectid,string"`
	Moduleid      int64 `json:"Moduleid,string"`
	Name          string
	Type          int64 `json:"Type,string"`
	Degree        int64 `json:"Degree,string"`
	Acceptid      int64 `json:"Acceptid,string"`
	Version       int64 `json:"Version,string"`
	Preconditions string
	Remarks       string
	Attachment    string
	Created       int64
	Createid      int64 `json:"Createid,string"`
	Status        int
	Changed       int64
	Changid       int64 `json:"Changid,string"`
}

type TestCaseDto struct {
	Id            int64 `orm:"pk;column(caseid);" json:"Id,string"`
	Projectid     int64 `json:"Projectid,string"`
	Projectname   string
	Moduleid      int64 `json:"Moduleid,string"`
	Modulename    string
	Name          string
	Type          int64 `json:"Type,string"`
	Degree        int64 `json:"Degree,string"`
	Acceptid      int64 `json:"Acceptid,string"`
	Version       int64 `json:"Version,string"`
	Preconditions string
	Remarks       string
	Attachment    string
	Created       int64
	Createid      int64 `json:"Createid,string"`
	Status        int
	Changed       int64
	Changid       int64 `json:"Changid,string"`
	Acceptname    string
}

func (this *TestCase) TableName() string {
	return models.TableName("projects_test_case")
}

func init() {
	orm.RegisterModel(new(TestCase))
}

/**
批量保存和更新
*/
func AddCases(userid int64, upd CaseStepDTO) (int64, error) {
	o := orm.NewOrm()
	d := new(TestCase)
	//雪花算法ID生成
	id := utils.SnowFlakeId()
	utils.SimpleCopyProperties(d, upd)
	d.Changid = userid
	d.Changed = time.Now().Unix()
	to, err := o.Begin()
	if !utils.IsEmpty(d.Id) {
		_, err = to.Update(d)
	} else {
		d.Id = id
		d.Createid = userid
		d.Created = time.Now().Unix()
		_, err = to.Insert(d)
	}
	if err != nil {
		eer := to.Rollback()
		logs.Info(eer.Error())
		return 0, err
	}
	if !utils.IsEmpty(upd.TestCaseStep) {
		for _, v := range upd.TestCaseStep {
			caseStep := new(TestCaseStep)
			utils.SimpleCopyProperties(caseStep, v)
			caseStep.Changid = userid
			caseStep.Created = time.Now().Unix()
			caseStep.Caseid = upd.Id
			if !utils.IsEmpty(v.Id) {
				_, err = to.Update(caseStep)
			} else {
				utils.UUID.Init(1024)
				stepid, _ := utils.UUID.GetId()
				caseStep.Id = stepid
				caseStep.Createid = userid
				caseStep.Changed = time.Now().Unix()
				_, err = to.Insert(caseStep)
			}
			if err != nil {
				break
			}
		}
	}
	if err != nil {
		eer := to.Rollback()
		logs.Info(eer.Error())
		return 0, err
	} else {
		eer := to.Commit()
		return id, eer
	}
}

func AddCase(upd TestCase) error {
	o := orm.NewOrm()
	needs := new(TestCase)

	needs.Id = upd.Id
	needs.Projectid = upd.Projectid
	utils.SimpleCopyProperties(needs, upd)
	needs.Created = time.Now().Unix()
	_, err := o.Insert(needs)
	return err
}

func UpdateCase(id int64, upd TestCase) error {
	var needs TestCase
	o := orm.NewOrm()
	needs = TestCase{Id: id}
	utils.SimpleCopyProperties(needs, upd)
	needs.Changed = time.Now().Unix()
	_, err := o.Update(&needs)
	return err

}

func GetCase(id int64) (TestCase, error) {
	var needs TestCase
	var err error
	o := orm.NewOrm()
	needs = TestCase{Id: id}
	err = o.Read(&needs)

	if err == orm.ErrNoRows {
		return needs, nil
	}
	return needs, err
}

func GetCaseByname(name string) (TestCase, error) {
	var module TestCase
	var err error
	o := orm.NewOrm()
	o.QueryTable(models.TableName("projects_test_case")).Filter("name", name).One(&module)
	if err == orm.ErrNoRows {
		return module, nil
	}
	return module, err
}

func CasePageExec(condArr map[string]interface{}, page int, offset int) (ops []TestCaseDto) {
	o := orm.NewOrm()
	var dto []TestCaseDto
	o.Raw(casePageSql(condArr, 1, page, offset)).QueryRows(&dto)
	return dto
}

func CaseNoPageExec(condArr map[string]interface{}) (ops []TestCaseDto) {
	o := orm.NewOrm()
	var dto []TestCaseDto
	o.Raw(casePageSql(condArr, 1, 1, 100000)).QueryRows(&dto)
	return dto
}
func CasePageCountExec(condArr map[string]interface{}, page int, offset int) int64 {
	o := orm.NewOrm()
	var Dto int64
	o.Raw(casePageSql(condArr, 0, page, offset)).QueryRow(&Dto)
	return Dto
}

/**
  组装sql
*/
func casePageSql(condArr map[string]interface{}, ifsCount, page int, offset int) (string, []interface{}) {
	var sql string
	if ifsCount == 0 {
		sql = sql + `SELECT count(1) FROM (`
	}
	sql = sql + `
		SELECT
		  c.*,
		  pp.name AS projectname,
		pm.name AS modulename,
		p.realname acceptname
		FROM  pms_projects pp INNER JOIN pms_projects_test_case c ON c.projectid=pp.projectid
		INNER JOIN  pms_users_profile p ON p.userid=c.acceptid
		LEFT JOIN  pms_projects_module pm ON pm.moduleid=c.moduleid
      WHERE 1 = 1 `
	param := make([]interface{}, 0, 0)
	if !utils.IsEmpty(condArr["projectid"]) {
		sql = sql + ` and  c.projectid=?`
		param = append(param, condArr["projectid"])
	}
	if !utils.IsEmpty(condArr["keyword"]) {
		sql = sql + ` and  c.name LIKE concat('%',?,'%')`
		param = append(param, condArr["keyword"])
	}
	if !utils.IsEmpty(condArr["typec"]) {
		sql = sql + ` and  c.type in(`
		sql1, value := cores.SqlInParam(condArr["typec"])
		sql = sql + sql1 + `)`
		param = append(param, value...)
	}
	if !utils.IsEmpty(condArr["acceptid"]) {
		sql = sql + ` and  c.acceptid in(`
		sql1, value := cores.SqlInParam(condArr["acceptid"])
		sql = sql + sql1 + `)`
		param = append(param, value...)
	}
	if !utils.IsEmpty(condArr["moduleid"]) {
		sql = sql + ` and  c.moduleid=?`
		param = append(param, condArr["moduleid"])
	}
	if !utils.IsEmpty(condArr["degree"]) {
		sql = sql + ` and  c.degree in(`
		sql1, value := cores.SqlInParam(condArr["degree"])
		sql = sql + sql1 + `)`
		param = append(param, value...)
	}
	if !utils.IsEmpty(condArr["status"]) {
		sql = sql + ` and  c.status in(`
		sql1, value := cores.SqlInParam(condArr["status"])
		sql = sql + sql1 + `)`
		param = append(param, value...)
	}
	if !utils.IsEmpty(condArr["ids"]) {
		sql = sql + ` and  c.caseid in(`
		sql1, value := cores.SqlInParam(condArr["ids"])
		sql = sql + sql1 + `)`
		param = append(param, value...)
	}
	if ifsCount == 0 {
		sql = sql + ` ) C`
	} else if ifsCount > 0 {
		if page < 1 {
			page = 1
		}
		if offset < 1 {
			offset, _ = beego.AppConfig.Int("pageoffset")
		}
		start := (page - 1) * offset
		startStr := strconv.Itoa(start)
		offsetStr := strconv.Itoa(offset)
		sql = sql + ` order by created desc LIMIT ` + startStr + `,` + offsetStr
	}
	return sql, param
}
